#ifndef __UTIL_H
#define __UTIL_H

#include <IceUtil/Thread.h>
#include <Imx.h>
#include <queue>
#include <vector>
#include "datatypes.h"
#include "config.h"
#include "datatypes.h"
#include "config.h"

using namespace std;

namespace Imx
{
//======定时通知线程===================================================================
// 负责定时向下位机广播
	class Notify : public IceUtil::Thread 
	{
		bool	_stopped;
		s16		_baseInterval;	// 基础时间间隔 ms
		s16		_hbCnt;			// hb通知间隔计数
		s16		_dataCnt;		// data通知间隔计数
	public:
		Notify();
		void run();			//	
	};
//======任务调度线程===================================================================
	class Loop  //  嵌套循环管理
	{   
		s32 _need;  // 记录当前循环需要执行几次
		s32 _cnt;   // 记录当前循环已经执行几次
		s32 _head;  // 记录当前循环起始工步
		s32 _tail;  // 记录当前循环结束工步
	public:
		Loop(s32,s32);
		s32 head();
		s32 need();
		void cnt();
		void cnt(int);
		s32 getCnt();
	};

	class TaskSchedule : public IceUtil::Thread, public IceUtil::Monitor<IceUtil::Mutex>// 工步任务线程
	{   
		bool _load;
		bool _hasLoop;
		bool _stopped;

		struct timespec _taskStartTs;
		struct timespec	_stepStartTs;

		u8	_flag;	//	运行标识，用于指示线程运行状态


		s32 _stepIdx;   // 工步执行索引
		u8  _devId;
		u8  _chnNo;

		Task _task;		//	已加载的工步
		queue<struct can_frame> _ackQueue; //应答消息队列
		vector<Loop> _loopStk;
	public:
		TaskSchedule();
		TaskSchedule(Task task):IceUtil::Thread(task.name),_task(task),_load(true),_hasLoop(false),_devId(task.devId),_chnNo(task.chnNo),_stepIdx(0){};
		~TaskSchedule();
		void run();
		Step popStep();
		bool isLoad();
		u8  getID();
		u8  getChn();

		s32	waitAck(u32 *can_id, s32 timeout);
		void putAck(struct can_frame);

		// thread ctrl func
		void pause();
		void cont();
		void stop();

		// time func
		u32	getTaskElapsed();
		u32	getStepElapsed();
	}; 

	// 任务执行线程的启动与管理
	class TaskManager
	{
		TaskSchedule* _taskTab[MAX_DEVS][MAX_CHN];
		queue<struct can_frame> _ackQueue; // 应答队列
	public:
		TaskManager();
		s32	loadTask(Task);					//	加载任务

		//	通道状态 chnState 控制	对应方法需要将全局状态描述gDevState[devId].csr[chnNo].chnState 改为对应数值
		s32	startTask(u8 devId, u8 chnNo);	//	开始任务	0x1充电 0x2放电 0x3静置  // 任务暂时由loadTask启动，保留该方法
		s32	stopTask(u8 devId, u8 chnNo);	//	停止任务	0x5停止
		s32 pauseTask(u8 devId, u8 chnNo);	//	暂停任务	0x1 0x2 0x3=>0x4暂停
		s32	contTask(u8 devId, u8 chnNo);	//	继续任务	0x4=>0x1 0x2 x03

		s32	clearTask(u8 devId, u8 chnNo);	//	清理任务	_taskTab[x][y] = NULL;

		s32	processAck(struct can_frame);	//	任务列表中务应答处理

		s32 waitAck(u32 *can_id, s32 timeout);
		void putAck(struct can_frame);

		s32 notifyEnd(u8 devId, u8 chnNo);	//	通知任务当前工步结束

		// time func
		u32	getTaskEla(u8 devId, u8 chnNo);
		u32	getStepEla(u8 devId, u8 chnNo);
	};
//======数据监听线程===================================================================
	class Listen : public IceUtil::Thread
	{
		bool	_stopped;
	public:
		Listen();
		void run();
	};

//======数据分析线程===================================================================
	class Analysis : public IceUtil::Thread
	{
		bool	_stopped;
		bool	_hasHead;
		queue<struct can_frame>	_chnReportQueue;	//	上传数据处理队列
	public:
		Analysis();
		void run();
		void process_HB_ACK(u8);					//	心跳处理
		void process_DATA_ACK();					//	数据处理
		void analysisData();
	};

	typedef struct
	{
		u8	devId;  // MAX_DEVS
		u8	chnId;  // MAX_CHN
		IceUtil::ThreadPtr	_handler;
	}ThreadInfo;
//=======Data Manager=======================================================================

	class DataManager
	{
		DevStateReport	_cachedDsr;
		string str_test;
	public:
		DataManager();
		~DataManager();
		void initTestData();
		ChnStateReport queryChnState(u8 devId, u8 chnNo);
		DevStateReport queryDevState(u8 devId);
		void hbCheck();
		void hbReset(u8 devId);
		void chnReset(u8 devId, u8 chnNo);		// 重置通道状态
		void chnSetName(u8 devId, u8 chnNo, string taskname);	//	设置通道任务名称
		void chnSetSeq(u8 devId, u8 chnNo, int seq);			//	设置通道工步序号

		s32	setChnEnd(u8 devId, u8 chnNo, Step ss);				//	设置通道结束条件	
		s32	checkVal(u32 endVal, u32 cntVal);					//	比较截至数据与统计数据，判断当前通道是否达到结束条件
		s32	updateChn(u8 devId, ChnReport cr);					//	更新通道数据
		s32 getDevState(u8 devId);
	};
}
#endif
